import dm5 from 'lib/dm5.js';

class Cache {
  static cache = {};

  static getKey(key) {
    let _key = key;
    if (typeof _key !== 'string') {
      _key = dm5(_key);
    }
    return _key;
  }

  static set(key, value, ms) {
    const _key = this.getKey(key);
    this.cache[_key] = {
      value,
      expireTime: Date.now() + ms,
      caching: false,
    };
  }

  static get(key) {
    const _key = this.getKey(key);
    const item = this.getDetail(_key);
    if (!item || item.caching) {
      return null;
    }
    if (item?.isExpired) {
      delete this.cache[_key];
      return null;
    }
    return item.value;
  }

  static getDetail(key) {
    const _key = this.getKey(key);
    const item = this.cache[_key];
    if (item) {
      const isExpired = Date.now() > item.expireTime;
      return {
        ...item,
        isExpired,
      };
    }
    return null;
  }

  // 设置为缓存中
  static setCaching(key) {
    const _key = this.getKey(key);
    this.cache[_key] = {
      value: null,
      expireTime: null,
      caching: true,
    };
  }

  // 是否在缓存中
  static isCaching(key) {
    const item = this.getDetail(key);
    if (item) {
      return item.caching;
    }
    return false;
  }

  static getAsync(key) {
    const _key = this.getKey(key);
    return new Promise(resolve => {
      let tryTimes = 10;
      const fn = () => {
        if (tryTimes <= 0) {
          resolve(null);
        }
        const detail = this.getDetail(_key);
        if (detail.caching) {
          tryTimes --;
          setTimeout(fn, 500);
        } else {
          resolve(detail.value);
        }
      };
      fn();
    });
  }
}

export default Cache;
